
#include "nodes/parse_nodes.h"
#include "main/main_entry.h"
#include "parser/analyze.h"
#include "parser/gram.tab.h"
#include "parser/parser.h"
#include "print/print.h"

list_t *parse_tree = NIL;
extern void *parser_init(oid_t *typev, int nargs);
extern int yyparse();
extern void init_io();
extern char* parse_string;

/**
* parser()
* \brief: call yacc and lex
* \param: str[in]
* \return: Query
* \note:
*/
query_t *parser(char *str, oid_t *typev, int nargs)
{
    query_t *result;
    int yyresult = 0;
    int i = 0;
    
    init_io();
    
    if (strlen(str) != 0)
    {
        parse_string = (char *)malloc(strlen(str) + 1);
        memmove(parse_string, str, strlen(str) + 1);
    }
    
    parser_init(typev, nargs);
    yyresult = yyparse();
    
    if (!yyresult)
    {
        result = parse_analyze(parse_tree);
        return result;
    }
    else
    {
        return (query_t *)NULL;
    }
}

/**
 * parser_typecast()
 * \brief:
 * \param:
 * \return:
 * \note:
 */
node_t *parser_typecast(parse_value_t *expr, type_name_t *type_name, int typ_len)
{

}

char* scanstr(char *s)
{
    static char newStr[MAX_PARSE_BUFFER];
    int len, i, start, j;
    char delimiter;

    if (s == NULL || s[0] == '\0')
    return s;

    len = strlen(s);
    start = 0;

    /* remove leading and trailing quotes, if any */
    /* the normal backend lexer only accepts single quotes, but the
       bootstrap lexer accepts double quotes */
    delimiter = 0;
    if (s[0] == '"' || s[0] == '\'')
    {
        delimiter = s[0];
        start = 1;
    }

    if (delimiter != 0)  {
        if (s[len-1] == delimiter)
            len = len - 1;
        else
            elog(WARN, "mismatched quote delimiters");
    }

    for (i = start, j = 0; i < len ; i++) {
        if (s[i] == '\'')
        {
            i = i + 1;
            if (s[i] == '\'')
            newStr[j] = '\'';
        }
        else
        {
            if (s[i] == '\\')
            {
                i = i + 1;
                switch (s[i])
                {
                case '\\':
                    newStr[j] = '\\';
                    break;
                case 'b':
                    newStr[j] = '\b';
                    break;
                case 'f':
                    newStr[j] = '\f';
                    break;
                case 'n':
                    newStr[j] = '\n';
                    break;
                case 'r':
                    newStr[j] = '\r';
                    break;
                case 't':
                    newStr[j] = '\t';
                    break;
                case '"':
                    newStr[j] = '"';
                    break;
                case '\'':
                    newStr[j] = '\'';
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                    {
                    char octal[4];
                    int k;
                    long octVal;

                    for (k=0;
                         s[i+k] >= '0' && s[i+k] <= '7' && k < 3;
                         k++)
                        octal[k] = s[i+k];
                    i += k-1;
                    octal[3] = '\0';

                    octVal = strtol(octal,0,8);
        /*			elog (NOTICE, "octal = %s octVal = %d, %od", octal, octVal, octVal);*/
                    if (octVal <= 0377)
                    {
                        newStr[j] = ((char)octVal);
                        break;
                    }
                }
                default:
    #ifdef ESCAPE_PATCH
                    newStr[j] = s[i];
    #else
                    elog (WARN, "Bad escape sequence, s[i] = %d", s[i]);
    #endif
                } /* switch */
            } /* s[i] == '\\' */
            else
            {
                newStr[j] = s[i];
            }
        }
        j++;
    }
    newStr[j] = '\0';
    return newStr;
}

